#pragma once

//#ifndef STDIO_H
//#define STDIO_H
//#endif

#include "stdio.h"
#include <boost\algorithm\string.hpp>
#include <boost\graph\adjacency_list.hpp>
#include <boost\pending\disjoint_sets.hpp>
#include <vector>
#include <map>
#include <myEdge.h>
#include <myVertex.h>
#include <mySystem.h>
#include <curlWrapper.h>
#include <conePlotter.h>
#include <colorMapper.h>
#include <time.h>
#include <fstream>

#define PI 3.14159

using namespace std;
using namespace boost;

class MwadjProcessor
{

public:
	
	MwadjProcessor(void);
	~MwadjProcessor(void);
	void processinput(string);
	
	void processTimeSortedData();

	void printTimeSortedData(string);
	
	void loadTimeSortedData(string,bool);

	void loadXYZCoordinates(string);

	template<typename xType,typename yType>
	int calAngle(xType,yType);

	void batchProcess(string,string,int);

	void readCSVfile(string);

	void readVertexCSVfile(string);

	void loadRGB(string);
	
	void printEdgeDetails(string);

	void printMetaFileDetails(string);

	map<int,int> findConnectedComponents();

	

	
	/*template<typename edgeElement,typename ticktimeType, typename timestampType,typename chiValType,typename sbpType> 
	void processEdge(edgeElement,ticktimeType,timestampType,vector<chiValType>&,sbpType);

	template<typename vertexElement,typename ticktimeType,typename chiValType,typename timestampType,typename sbpType> 
	void processVertex(vertexElement,ticktimeType,timestampType,vector<chiValType>&,sbpType);

	template <typename sysFreqType,typename tickNoType,typename chiValType,typename timestampType,typename sbpType>
	void processSystem(sysFreqType,tickNoType,timestampType,vector<chiValType>&, sbpType&);

	template<typename vertexElement, typename disjointsetType> 
	void updateMST(vertexElement,vertexElement,disjointsetType&);

	template<typename myDataType> 
	int compareFunction(myDataType,myDataType);

	template<typename param1Type, typename param2Type>
	float calculate_sbp(param1Type, param2Type);

	template<typename param1Type, typename param2Type>
	float calc_edge_disc_wt(param1Type,param2Type);*/



private :


	int no_of_vertices;
	int no_of_edges;
	int overall_ticks;
	int max_chi_vertex;
	int min_chi_vertex;
	int max_chi_edge;
	int min_chi_edge;
	int max_freq_vertex;
	int min_freq_vertex;
	int max_freq_edge;
	int min_freq_edge;
	int no_of_edge_replacements;
	int no_of_new_edge_added;
	float max_sbp_vertex;
	float min_sbp_vertex;
	float max_sbp_edge;
	float min_sbp_edge;
	string ipdir;

	map<double,vector<string> > time_sorted_mwadj;
	map<string,int> edge_id_mapping;
	map<int,int> vertex_id_mapping;
	map<int,myEdge> edge_properties;
	map<int,myVertex> vertex_properties;
	map<double,mySystem> system_properties;
	double timetosend;

	typedef adjacency_list <vecS, vecS, undirectedS, property<vertex_index_t,int>,property<edge_index_t, int> > Graph;
	
	typedef int* Rank;
	typedef int* Parent;

	typedef disjoint_sets<Rank, Parent> mydisjointSet;
	
	ofstream edgemetadetailspointer;
	Graph inputGraph;
	Graph MSTGraph;
	
	curlWrapper mycurl_edge;
	curlWrapper mycurl_vertex;
	curlWrapper mycurl_graph;
	curlWrapper mycurl_entire_graph;
	
	struct XYZcoord {
		float X;
		float Y;
		float Z;
	};
	map<int,XYZcoord> nodeXYZ;
	struct rgb{
		int r;
		int g;
		int b;
	};
	map<int,rgb> nodeRGB;
	map<int,string> nodeLabel;
	
	struct sbp_det_struct {
		int max_chi;
		int min_chi;
		int min_id;
		int max_id;
	};

	

	map<float,sbp_det_struct> sbp_list_edge;

	map<float,sbp_det_struct> sbp_list_vertex;

	template<typename edgeElement,typename ticktimeType, typename timestampType,typename chiValType,typename sbpType> 
	void processEdge(edgeElement,ticktimeType,timestampType,vector<chiValType>&,sbpType,int,int);

	template<typename vertexElement,typename ticktimeType,typename chiValType,typename timestampType,typename sbpType> 
	void processVertex(vertexElement,ticktimeType,timestampType,vector<chiValType>&,sbpType);

	template <typename sysFreqType,typename tickNoType,typename chiValType,typename timestampType,typename sbpType>
	void processSystem(sysFreqType,tickNoType,timestampType,vector<chiValType>&, sbpType&);

	template<typename vertexElement, typename disjointsetType> 
	void updateMST(vertexElement,vertexElement,disjointsetType&,float,bool);

	template<typename vertexElement> 
	void updateInputGraph(vertexElement,vertexElement,bool);

	template<typename myDataType> 
	int compareFunction(myDataType,myDataType);

	template<typename param1Type, typename param2Type>
	float calculate_sbp(param1Type, param2Type);

	template<typename param1Type, typename param2Type>
	float calc_edge_disc_wt(param1Type,param2Type);

	typedef graph_traits < Graph >::degree_size_type deg_size_type;

	void initialiseDisjointSets(mydisjointSet &);
	void printVertexMapping(string);

	conePlotter mytempCone;

	colorMapper myColormap;

	
public:

	void findPlanarXY(Graph, string);
	void testPlanar();
	void testPlanar1();
	bool checkUniqEdges();
	string getIpDir();
	bool setIpDir(string);


};

